package com.leetroll.app.annotation.log;

import com.leetroll.app.global.SysConf;
import com.leetroll.common.constant.CharConstant;
import com.leetroll.common.constant.RedisConstant;
import com.leetroll.common.entity.UserBehavior;
import com.leetroll.common.holder.AbstractRequestAwareRunnable;
import com.leetroll.common.utils.IpUtils;
import com.leetroll.common.utils.RedisUtil;
import com.leetroll.common.utils.StringUtils;
import java.util.concurrent.TimeUnit;

/**
 * 异步记录日志
 */

public class SysLogHandle extends AbstractRequestAwareRunnable {

    /**
     * 模块ID
     */
    String moduleId;
    /**
     * itemId
     */
    String itemId;
    /**
     * 其它数据
     */
    String otherData;
    /**
     * Redis工具类对象
     */
    private final RedisUtil redisUtil;
    /**
     * 用户UID
     */
    private final String userId;
    /**
     * 用户行为
     */
    private final String behavior;

    /**
     * ip地址
     */
    private final String ip;

    /**
     * 操作系统
     */
    private final String os;

    /**
     * 浏览器
     */
    private final String browser;

    /**
     * 构造函数
     */
    public SysLogHandle(String userId, String ip, String os, String browser, String behavior, String moduleId,String otherData, RedisUtil redisUtil) {
        this.userId = userId;
        this.ip = ip;
        this.os = os;
        this.browser = browser;
        this.behavior = behavior;
        this.moduleId = moduleId;
//        this.itemId = itemId;
        this.otherData = otherData;
        this.redisUtil = redisUtil;
    }


    /**
     * 遇见语录：Request请求结束后，异步线程拿主进程里数据会出现空指针异常【因此不能在子线程里操作Request对象】
     * 这个问题不一定每一次都出现，可能100次中有4~5次出现空指针异常，也就是说当 异步线程执行比主线程快 是没问题的
     * 这里为了避免这种情况，将避免在异步线程中操作Request对象
     */
    @Override
    protected void onRun() {
        UserBehavior userBehavior = new UserBehavior();

        userBehavior.setIp(ip);
        //从Redis中获取IP来源
        String jsonResult = redisUtil.get(RedisConstant.IP_SOURCE + CharConstant.SYMBOL_COLON + ip);
        if (StringUtils.isEmpty(jsonResult)) {
            String addresses = IpUtils.getAddresses(SysConf.IP + SysConf.EQUAL_TO + ip, SysConf.UTF_8);
            if (StringUtils.isNotEmpty(addresses)) {
                userBehavior.setIpSource(addresses);
                redisUtil.setEx(RedisConstant.IP_SOURCE + CharConstant.SYMBOL_COLON + ip, addresses, 24, TimeUnit.HOURS);
            }
        } else {
            userBehavior.setIpSource(jsonResult);
        }
        userBehavior.setOs(os);
        userBehavior.setBrowser(browser);
        userBehavior.setUserId(userId);
        userBehavior.setBehavior(behavior);
        userBehavior.setModuleId(moduleId);
        userBehavior.setItemId(itemId);
        userBehavior.setOtherData(otherData);
        userBehavior.insert();
    }
}
